// 参数解析模块
use crate::config::{CliArgs, ExecutionMode, InterpreterConfig, OperationMode, OutputFormat};
use std::time::Duration;

/// 参数解析错误
#[derive(Debug, Clone)]
pub enum ParseError {
    UnknownFlag(String),
    InvalidValue {
        flag: String,
        value: String,
        expected: String,
    },
    MissingValue {
        flag: String,
    },
    InvalidNumber {
        flag: String,
        value: String,
    },
    InvalidDuration {
        flag: String,
        value: String,
    },
    ConflictingOptions {
        flag1: String,
        flag2: String,
    },
}

impl std::fmt::Display for ParseError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ParseError::UnknownFlag(flag) => write!(f, "未知标志: {}", flag),
            ParseError::InvalidValue {
                flag,
                value,
                expected,
            } => {
                write!(f, "标志 {} 的值 '{}' 无效，期望: {}", flag, value, expected)
            }
            ParseError::MissingValue { flag } => write!(f, "标志 {} 缺少值", flag),
            ParseError::InvalidNumber { flag, value } => {
                write!(f, "标志 {} 的值 '{}' 不是有效数字", flag, value)
            }
            ParseError::InvalidDuration { flag, value } => {
                write!(f, "标志 {} 的值 '{}' 不是有效时间格式", flag, value)
            }
            ParseError::ConflictingOptions { flag1, flag2 } => {
                write!(f, "标志 {} 和 {} 不能同时使用", flag1, flag2)
            }
        }
    }
}

impl std::error::Error for ParseError {}

/// 命令行参数解析器
pub struct ArgParser {
    args: Vec<String>,
    current: usize,
}

impl ArgParser {
    pub fn new(args: Vec<String>) -> Self {
        Self { args, current: 0 }
    }

    /// 解析所有参数
    pub fn parse(&mut self) -> Result<CliArgs, ParseError> {
        let mut cli_args = CliArgs::default();

        // 跳过程序名
        self.advance();

        if self.is_at_end() {
            return Ok(cli_args);
        }

        // 先解析所有标志参数
        while !self.is_at_end() && self.current_arg().starts_with("-") {
            self.parse_flag(&mut cli_args)?;
        }

        // 然后解析操作模式和文件参数
        if !self.is_at_end() {
            match self.current_arg().as_str() {
                "repl" => {
                    cli_args.mode = OperationMode::Repl;
                    self.advance();
                }
                "run" => {
                    cli_args.mode = OperationMode::Run;
                    self.advance();
                    if !self.is_at_end() && !self.current_arg().starts_with("-") {
                        cli_args.input_file = Some(self.current_arg().clone());
                        self.advance();
                    }
                }
                "check" => {
                    cli_args.mode = OperationMode::Check;
                    self.advance();
                    if !self.is_at_end() && !self.current_arg().starts_with("-") {
                        cli_args.input_file = Some(self.current_arg().clone());
                        self.advance();
                    }
                }
                "format" => {
                    cli_args.mode = OperationMode::Format;
                    self.advance();
                    if !self.is_at_end() && !self.current_arg().starts_with("-") {
                        cli_args.input_file = Some(self.current_arg().clone());
                        self.advance();
                    }
                }
                "help" | "--help" | "-h" => {
                    cli_args.mode = OperationMode::Help;
                    self.advance();
                }
                "version" | "--version" | "-v" => {
                    cli_args.mode = OperationMode::Version;
                    self.advance();
                }
                _ => {
                    // 默认模式：运行文件
                    cli_args.mode = OperationMode::Run;
                    cli_args.input_file = Some(self.current_arg().clone());
                    self.advance();
                }
            }
        }

        // 解析剩余的标志参数（在模式之后的）
        while !self.is_at_end() {
            self.parse_flag(&mut cli_args)?;
        }

        // 验证参数一致性
        self.validate_args(&cli_args)?;

        Ok(cli_args)
    }

    fn parse_flag(&mut self, cli_args: &mut CliArgs) -> Result<(), ParseError> {
        let flag = self.current_arg().clone();

        match flag.as_str() {
            "--config" | "-c" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                cli_args.config_file = Some(self.current_arg().clone());
                self.advance();
            }
            "--output" | "-o" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                // 注意：CliArgs没有output_file字段，这个标志暂时不支持
                self.advance();
            }
            "--format" | "-f" | "--output-format" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                let format_str = self.current_arg().clone();
                cli_args.config.output_format = match format_str.to_lowercase().as_str() {
                    "plain" => OutputFormat::Plain,
                    "json" => OutputFormat::Json,
                    "colored" => OutputFormat::Colored,
                    _ => {
                        return Err(ParseError::InvalidValue {
                            flag: flag.clone(),
                            value: format_str,
                            expected: "plain, json, or colored".to_string(),
                        });
                    }
                };
                self.advance();
            }
            "--debug" | "-d" => {
                cli_args.config.execution_mode = ExecutionMode::Debug;
                cli_args.config.show_statistics = true;
                self.advance();
            }
            "--quiet" | "-q" => {
                cli_args.config.execution_mode = ExecutionMode::Quiet;
                self.advance();
            }
            "--verbose" | "-V" => {
                cli_args.config.execution_mode = ExecutionMode::Verbose;
                cli_args.config.show_statistics = true;
                self.advance();
            }
            "--json" | "-j" => {
                cli_args.config.output_format = OutputFormat::Json;
                self.advance();
            }
            "--colored" | "--color" => {
                cli_args.config.output_format = OutputFormat::Colored;
                self.advance();
            }
            "--no-optimize" => {
                cli_args.config.enable_optimizations = false;
                self.advance();
            }
            "--no-safety" => {
                cli_args.config.enable_safety_checks = false;
                self.advance();
            }
            "--stats" | "-s" => {
                cli_args.config.show_statistics = true;
                self.advance();
            }
            "--no-cache" => {
                cli_args.config.enable_module_cache = false;
                self.advance();
            }
            "--timeout" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                let timeout_str = self.current_arg().clone();
                match timeout_str.parse::<u64>() {
                    Ok(seconds) => {
                        cli_args.config.resource_limits.max_execution_time =
                            Some(Duration::from_secs(seconds));
                        self.advance();
                    }
                    Err(_) => {
                        return Err(ParseError::InvalidDuration {
                            flag: flag.clone(),
                            value: timeout_str,
                        });
                    }
                }
            }
            "--max-memory" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                let memory_str = self.current_arg().clone();
                match parse_memory_size(&memory_str) {
                    Ok(bytes) => {
                        cli_args.config.resource_limits.max_memory_usage = Some(bytes);
                        self.advance();
                    }
                    Err(_) => {
                        return Err(ParseError::InvalidValue {
                            flag: flag.clone(),
                            value: memory_str,
                            expected: "内存大小 (如: 100M, 1G)".to_string(),
                        });
                    }
                }
            }
            "--max-loops" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                let loops_str = self.current_arg().clone();
                match loops_str.parse::<u64>() {
                    Ok(iterations) => {
                        cli_args.config.resource_limits.max_loop_iterations = Some(iterations);
                        self.advance();
                    }
                    Err(_) => {
                        return Err(ParseError::InvalidNumber {
                            flag: flag.clone(),
                            value: loops_str,
                        });
                    }
                }
            }
            "--max-recursion" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                let recursion_str = self.current_arg().clone();
                match recursion_str.parse::<u32>() {
                    Ok(depth) => {
                        cli_args.config.resource_limits.max_recursion_depth = Some(depth);
                        self.advance();
                    }
                    Err(_) => {
                        return Err(ParseError::InvalidNumber {
                            flag: flag.clone(),
                            value: recursion_str,
                        });
                    }
                }
            }
            "--module-path" | "-m" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                cli_args.module_paths.push(self.current_arg().clone());
                self.advance();
            }
            "--encoding" => {
                self.advance();
                if self.is_at_end() {
                    return Err(ParseError::MissingValue { flag: flag.clone() });
                }
                cli_args.config.encoding = self.current_arg().clone();
                self.advance();
            }
            "--safe-mode" => {
                cli_args.config = InterpreterConfig::safe_mode_config();
                self.advance();
            }
            "--performance-mode" => {
                cli_args.config = InterpreterConfig::performance_config();
                self.advance();
            }
            _ => return Err(ParseError::UnknownFlag(flag.clone())),
        }

        Ok(())
    }

    fn validate_args(&self, cli_args: &CliArgs) -> Result<(), ParseError> {
        // 检查冲突的选项
        if cli_args.config.execution_mode == ExecutionMode::Quiet && cli_args.config.show_statistics
        {
            return Err(ParseError::ConflictingOptions {
                flag1: "--quiet".to_string(),
                flag2: "--stats".to_string(),
            });
        }

        if cli_args.config.execution_mode == ExecutionMode::Debug
            && cli_args.config.execution_mode == ExecutionMode::Quiet
        {
            return Err(ParseError::ConflictingOptions {
                flag1: "--debug".to_string(),
                flag2: "--quiet".to_string(),
            });
        }

        Ok(())
    }

    fn current_arg(&self) -> &String {
        &self.args[self.current]
    }

    fn advance(&mut self) {
        if !self.is_at_end() {
            self.current += 1;
        }
    }

    fn is_at_end(&self) -> bool {
        self.current >= self.args.len()
    }
}

/// 解析内存大小字符串 (如 "100M", "1G")
fn parse_memory_size(size_str: &str) -> Result<usize, String> {
    let size_str = size_str.trim().to_uppercase();

    if let Some(pos) = size_str.find('K') {
        let number = size_str[..pos].parse::<usize>().map_err(|_| "无效的数字")?;
        return Ok(number * 1024);
    }

    if let Some(pos) = size_str.find('M') {
        let number = size_str[..pos].parse::<usize>().map_err(|_| "无效的数字")?;
        return Ok(number * 1024 * 1024);
    }

    if let Some(pos) = size_str.find('G') {
        let number = size_str[..pos].parse::<usize>().map_err(|_| "无效的数字")?;
        return Ok(number * 1024 * 1024 * 1024);
    }

    // 纯数字，按字节计算
    size_str
        .parse::<usize>()
        .map_err(|_| "无效的内存大小格式".to_string())
}

/// 显示帮助信息
pub fn show_help() {
    println!("墨言·文心 v0.1.0 - 中文编程语言解释器");
    println!();
    println!("用法: moyan [模式] [选项] [文件]");
    println!();
    println!("模式:");
    println!("  run <文件>       运行指定的墨言文件");
    println!("  repl             启动交互式解释器");
    println!("  check <文件>     检查文件语法");
    println!("  format <文件>     格式化文件");
    println!("  help             显示此帮助信息");
    println!("  version          显示版本信息");
    println!();
    println!("选项:");
    println!("  -c, --config <文件>     指定配置文件");
    println!("  -d, --debug             启用调试模式");
    println!("  -q, --quiet             启用静默模式");
    println!("  -V, --verbose           启用详细模式");
    println!("  -j, --json              使用JSON输出格式");
    println!("  --colored, --color       使用彩色输出");
    println!("  --no-optimize            禁用优化");
    println!("  --no-safety              禁用安全检查");
    println!("  -s, --stats              显示执行统计信息");
    println!("  --no-cache               禁用模块缓存");
    println!("  --timeout <秒>           设置执行超时时间");
    println!("  --max-memory <大小>      设置最大内存使用量 (如: 100M, 1G)");
    println!("  --max-loops <次数>       设置最大循环迭代次数");
    println!("  --max-recursion <深度>   设置最大递归深度");
    println!("  -m, --module-path <路径> 添加模块搜索路径");
    println!("  --encoding <编码>         设置文件编码");
    println!("  --safe-mode              启用安全模式（严格限制）");
    println!("  --performance-mode       启用性能模式（优化执行）");
    println!();
    println!("示例:");
    println!("  moyan run hello.墨言                    # 运行文件");
    println!("  moyan --debug run test.墨言             # 调试模式运行");
    println!("  moyan --timeout 5 run script.墨言       # 5秒超时运行");
    println!("  moyan --max-memory 50M --safe-mode repl # 安全模式REPL");
    println!("  moyan --json --stats run prog.墨言      # JSON输出带统计");
}

/// 显示版本信息
pub fn show_version() {
    use crate::{BUILD_DATE, NAME, RUST_VERSION, TARGET_ARCH, TARGET_OS, VERSION};

    println!("墨言·文心 v{} - 中文编程语言解释器", VERSION);
    println!("{}", "═".repeat(50));
    println!("项目信息:");
    println!("  名称: {}", NAME);
    println!("  版本: {}", VERSION);
    println!("  构建日期: {}", BUILD_DATE);
    println!();
    println!("技术信息:");
    println!("  编程语言: Rust {}", RUST_VERSION);
    println!("  编译器: {}", RUST_VERSION);
    println!("  平台: {} {}", TARGET_OS, TARGET_ARCH);
    println!(
        "  构建类型: {}",
        if cfg!(debug_assertions) {
            "Debug"
        } else {
            "Release"
        }
    );
    println!(
        "  特性组: {}",
        if cfg!(feature = "advanced-cli") {
            "高级CLI"
        } else {
            "标准CLI"
        }
    );
    println!();
    println!("版权信息:");
    println!(
        "  © {} 墨言开发团队",
        BUILD_DATE.split_terminator('-').next().unwrap()
    );
    println!("  许可协议: MIT");
    println!("  仓库: https://github.com/moyan-lang/moyan");
    println!();
    println!("使用方法:");
    println!("  moyan help     显示完整帮助");
    println!("  moyan version  显示版本信息");
    println!("  moyan repl       启动交互模式");
    println!("  moyan run <文件>  运行墨言文件");
}
